大家好,我是 Yubin
這篇文章會介紹 Fastify 生態系中對 Database 的支援,以及透過 Docker 啟動一個 MongoDB Container 來實際玩玩看。
Fastify 官方維護了許多關於資料庫的 Plugin:
除了官方維護的套件外,還有社群提供的許多跟資料庫進行互動的 Plugin。
本篇以 MongoDB 為例。
MongoDB 是一個文件式 (document) 的資料庫。
不用像關聯式資料庫一樣需要先定義好 Tabke Schema,直接把資料放進去就可以使用。
一筆"文件",可能會看起來像這樣:
{
name: "Yubin",
email: "yubin.taiwan@gmail.com"
}
沒錯,看起來就像個 JSON 格式的字串,MongoDB 對 JavaScript 非常友善。
我們可以直接把某個 JavaScript 的物件,直接存放進 MongoDB 中,可以想像成是把某個物件當時的狀態,直接快照 (snapshot) 進資料庫。
我們要如何開發與 MongoDB 互動的程式呢?
一個方式是去 MongoDB 的官網,根據所使用的作業系統,下載 MongoDB Server 的安裝檔或執行檔,然後啟動 MongoDB 的伺服器。
但更快且更建議的做法是,使用 Container。
如果你安經安裝了 Docker 或 Podman,就可以在 terminal 下指令,把 MongoDB Container 跑起來。
docker run -d -p 27017:27017 --name=mongo-server mongo
執行完後,再執行:
docker ps
如果有看到 mongo-server 正在執行中,就代表啟動成功。
如果使用的是 podman,
把docker run
改為podman run
,以及docker ps
改為podman ps
即可。
我們起好 MongoDB Container 之後,可以下載官方的 MongoDB Compass。
MongoDB Compass 是一個視覺化的 MongoDB Client 工具,可以幫助你瀏覽某一座 MongoDB Server 上的資料,以及可以透過圖形化的介面去新增、修改、刪除上面的紀錄。
安裝好之後開啟程式。
會看到要求輸入 Connection 的提示。
Connection String,連線字串,這個字串記錄了要連的 MongoDB Server 的資訊,以及登入的帳號密碼或資料庫。
官方描述的 Connection String 規格如下:
mongodb://[username:password@]host1[:port1][,...hostN[:portN]][/[defaultauthdb][?options]]
開頭必定要是 mongodb://
然後如果登入該資料庫需要帳號密碼,可以用 :
串起來。
例如,user01:password01
如果有輸入帳號密碼的話,加上 @
串上主機名稱。
:port
,MongoDB Server 愈設的 Port 是 27017
。
/defaultauthdb
預設使用的資料庫,沒有設定的話會使用該登入帳號預設的資料庫。
因為我們利用 Docker 將 MongoDB Container 起在本機 (localhost),該 image 也沒有預設的帳號密碼,
所以我們使用的 Connection String 是:
mongodb://localhost:27017
輸入這個 Connection String 就可以透過 MongoDB Compass 登入 MongoDB Server。
是的,一開始沒有資料,只有 MongoDB 預設的幾個 Collection。
@fastify/mongodb 是官方維護的 MongoDB Plugin。
透過 npm 安裝:
npm i @fastify/mongodb
接著在程式中 import 套件,並註冊他。
import fastifyMongodb from '@fastify/mongodb'
server.register(fastifyMongodb, {
forceClose: true,
url: 'mongodb://localhost:27017/my-fastify'
})
forceClose
參數表示在應用程式結束的時候,也把 MongoDB 的連線關閉,
預設為 false
。
url
帶入 MongoDB 的 Connection String。(這邊使用 my-fastify
資料庫)
就完成註冊的工作了。
@fastify/mongodb
會註冊一個 MongoDB Client 的 decorator 在 FastifyInstance。
我們定義一個 Post /users
的 route 來搭配將資料寫進 MongoDB:
interface UserRequestBody {
name: string
email: string
}
server.post<{ Body: UserRequestBody }>('/users', async (request, reply) => {
const name = request.body.name
const email = request.body.email
try {
const users = server.mongo.db?.collection('users')
const user = await users?.insertOne({
name: name,
email: email
})
return reply.status(201).send({ user })
} catch (error) {
return reply.status(500).send({ error })
}
})
定義 reuqest.body
會拿到 name 跟 email 的欄位,且型態都是字串。
透過 server.mongo.db
拿到 MongoDB Client 物件,取得 collection 後,透過 .insertOne()
來插入資料。
接著透過 Postman 等 API Client 工具,發送 POST Request。
Payload 帶入 name 及 email 的值。
發送後可以看到 201 Created
的回應,表示成功沒有問題。
接著打開 MongoDB Compass,可以觀察到資料確實被寫進資料庫中。
自此對於資料庫的串接實驗就完成了。
在 Fastify 的官網中還有許多對於不同 Database 的範例,有興趣的人可以去尋找適合的 Plugin 來使用。